/******************************************************************************
 *
 * @file       singleton.h
 * @brief      单例模式基类
 *
 * @author     ario
 * @date       2024/05/13
 * @history
 *****************************************************************************/

#ifndef SINGLETON_H
#define SINGLETON_H

#include <memory>
#include <mutex>
#include <iostream>

template <typename T>
class Singleton{
public:
    static std::shared_ptr<T> GetInstance() {
        static std::once_flag s_flag; // s_flag访问过一次就会从false变为true
        std::call_once(s_flag, [&](){
            _instance = std::shared_ptr<T>(new T); // 继承模板类子类的构造会设置为private，make_sharead无法访问私有构造函数
        });
        return _instance;

        /*
            C++11后，静态局部变量都是线程安全的
            所以单例可以用以下写法
            static T& getInstance() {
                static T instance;
                return instance;
            }
        */

    }

    void PrintAddress() {
        std::cout << _instance.get() << std::endl;
    }

    ~Singleton() {
//        std::cout << "this is singleton destruct" << std::endl;
    }
protected:
    Singleton() = default; // 为了让子类有构造函数，模板单例类的构造函数不能删除
    Singleton(const Singleton<T> &) = delete; // 删除拷贝构造函数
    Singleton& operator = (const Singleton<T> &) = delete; // 删除赋值运算符函数
protected:
    static std::shared_ptr<T> _instance; // 使用智能指针管理单例类的指针
};

template <typename T>
std::shared_ptr<T> Singleton<T>::_instance = nullptr; // 使用了模板，静态数据成员就可以在头文件中初始化

#endif // SINGLETON_H
